package com.campus.counseling.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.campus.counseling.entity.AIChatMessage;
import com.campus.counseling.entity.AIChatSession;
import com.campus.counseling.entity.TestResult;
import com.campus.counseling.model.common.exception.ServiceException;
import com.campus.counseling.model.mapper.AIChatMessageMapper;
import com.campus.counseling.model.mapper.AIChatSessionMapper;
import com.campus.counseling.service.AIChatService;
import com.campus.counseling.service.TestResultService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class AIChatServiceImpl implements AIChatService {

    private final AIChatSessionMapper sessionMapper;
    private final AIChatMessageMapper messageMapper;
    private final TestResultService testResultService;

    @Value("${spark.app-id}")
    private String appId;

    @Value("${spark.api-key}")
    private String apiKey;

    @Value("${spark.api-secret}")
    private String apiSecret;

    @Value("${spark.api-url}")
    private String apiUrl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AIChatSession createSession(Long userId, Long recordId) {
        log.info("创建新的AI聊天会话, userId: {}, recordId: {}", userId, recordId);

        // 先通过 recordId 获取 TestResult
        TestResult testResult = testResultService.getByRecordId(recordId);

        AIChatSession session = new AIChatSession();
        session.setUserId(userId);
        session.setTitle("新对话");
        session.setStatus("ACTIVE");
        session.setTestResultId(testResult != null ? testResult.getId() : null);
        session.setCreateTime(LocalDateTime.now());
        session.setUpdateTime(LocalDateTime.now());

        sessionMapper.insert(session);

        // 创建欢迎消息
        AIChatMessage welcomeMessage = new AIChatMessage();
        welcomeMessage.setSessionId(session.getId());
        welcomeMessage.setRole("assistant");
        welcomeMessage.setContent("您好！我是您的AI心理咨询助手。我可以帮助您缓解压力、改善情绪。您可以直接告诉我您的困扰，或者分享您的心理测试结果，我会为您提供更有针对性的建议。");
        welcomeMessage.setCreateTime(LocalDateTime.now());
        messageMapper.insert(welcomeMessage);

        // 如果有测试记录ID，自动发送测试结果链接消息
        if (recordId != null) {
            AIChatMessage testResultMessage = new AIChatMessage();
            testResultMessage.setSessionId(session.getId());
            testResultMessage.setRole("user");
            testResultMessage.setContent("[查看我的心理测试结果](#/test/result/" + recordId + ")");
            testResultMessage.setCreateTime(LocalDateTime.now());
            messageMapper.insert(testResultMessage);

            // AI回应测试结果
            if (testResult != null) {
                AIChatMessage analysisMessage = new AIChatMessage();
                analysisMessage.setSessionId(session.getId());
                analysisMessage.setRole("assistant");
                analysisMessage.setContent(buildTestResultAnalysis(testResult));
                analysisMessage.setCreateTime(LocalDateTime.now());
                messageMapper.insert(analysisMessage);
            }
        }

        return session;
    }

    @Override
    public List<AIChatSession> getSessionList(Long userId) {
        return sessionMapper.selectList(new LambdaQueryWrapper<AIChatSession>()
                .eq(AIChatSession::getUserId, userId)
                .eq(AIChatSession::getStatus, "ACTIVE")
                .orderByDesc(AIChatSession::getUpdateTime));
    }

    @Override
    public List<AIChatMessage> getSessionMessages(Long sessionId) {
        return messageMapper.selectList(new LambdaQueryWrapper<AIChatMessage>()
                .eq(AIChatMessage::getSessionId, sessionId)
                .orderByAsc(AIChatMessage::getCreateTime));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AIChatMessage sendMessage(Long sessionId, String content) {
        log.info("开始处理用户消息: sessionId={}, content={}", sessionId, content);

        // 1. 保存用户消息
        AIChatMessage userMessage = new AIChatMessage();
        userMessage.setSessionId(sessionId);
        userMessage.setRole("user");
        userMessage.setContent(content);
        userMessage.setCreateTime(LocalDateTime.now());
        messageMapper.insert(userMessage);

        try {
            // 2. 生成AI回复
            String aiResponse = generateAIResponse(content);
            log.info("生成的AI回复: {}", aiResponse);

            // 3. 保存AI回复
            AIChatMessage aiMessage = new AIChatMessage();
            aiMessage.setSessionId(sessionId);
            aiMessage.setRole("assistant");
            aiMessage.setContent(aiResponse);
            aiMessage.setCreateTime(LocalDateTime.now());
            messageMapper.insert(aiMessage);

            // 4. 更新会话时间
            AIChatSession session = new AIChatSession();
            session.setId(sessionId);
            session.setUpdateTime(LocalDateTime.now());
            sessionMapper.updateById(session);

            return aiMessage;

        } catch (Exception e) {
            log.error("发送消息失败", e);
            throw new ServiceException("消息发送失败，请稍后重试");
        }
    }

    private String generateAIResponse(String userMessage) {
        try {
            log.info("开始生成AI回复");
            
            StringBuilder prompt = new StringBuilder();
            prompt.append("你是一位专业的心理咨询助手，请基于以下用户输入提供专业、温和的回应：\n\n");
            
            // 添加特定场景建议
            if (userMessage.contains("考试")) {
                prompt.append("这是一个关于考试焦虑的咨询，请：\n");
                prompt.append("1. 分享考试压力管理技巧\n");
                prompt.append("2. 讨论合理的学习计划\n");
                prompt.append("3. 建议适度休息和调节\n");
            } else if (userMessage.contains("人际")) {
                prompt.append("这是一个关于人际关系的咨询，请：\n");
                prompt.append("1. 讨论沟通技巧\n");
                prompt.append("2. 分析人际互动模式\n");
                prompt.append("3. 建议社交支持网络建设\n");
            }
            
            prompt.append("\n【用户原文】\n").append(userMessage);
            
            log.info("生成的提示词: {}", prompt);
            
            return callSparkAPI(prompt.toString());
            
        } catch (Exception e) {
            log.error("生成AI回复失败", e);
            throw new ServiceException("AI服务暂时不可用，请稍后重试");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSessionTitle(Long sessionId, String title) {
        log.info("更新AI聊天会话标题, sessionId: {}, title: {}", sessionId, title);

        // 参数校验
        if (sessionId == null || title == null || title.trim().isEmpty()) {
            throw new IllegalArgumentException("参数不能为空");
        }

        // 获取会话
        AIChatSession session = sessionMapper.selectById(sessionId);
        if (session == null) {
            throw new RuntimeException("会话不存在");
        }

        // 更新标题
        session.setTitle(title.trim());
        session.setUpdateTime(LocalDateTime.now());

        // 保存更新
        int rows = sessionMapper.updateById(session);
        if (rows != 1) {
            throw new RuntimeException("更新失败");
        }

        log.info("AI聊天会话标题更新成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSession(Long sessionId) {
        // 先删除会话相关的所有消息
        messageMapper.delete(new LambdaQueryWrapper<AIChatMessage>()
                .eq(AIChatMessage::getSessionId, sessionId));

        // 再删除会话
        sessionMapper.deleteById(sessionId);

        log.info("AI聊天会话及相关消息删除成功");
    }

    @Override
    public AIChatSession findActiveSessionByTestResult(Long userId, Long testResultId) {
        return sessionMapper.selectOne(new LambdaQueryWrapper<AIChatSession>()
                .eq(AIChatSession::getUserId, userId)
                .eq(AIChatSession::getTestResultId, testResultId)
                .eq(AIChatSession::getStatus, "ACTIVE")
                .orderByDesc(AIChatSession::getCreateTime)
                .last("LIMIT 1"));
    }

    private String callSparkAPI(String content) {
        try {
            // 生成鉴权URL
            String authUrl = getAuthUrl();

            // 创建WebSocket连接
            OkHttpClient client = new OkHttpClient.Builder()
                    .pingInterval(40, TimeUnit.SECONDS)
                    .build();

            // 使用CompletableFuture来处理异步响应
            CompletableFuture<String> responseFuture = new CompletableFuture<>();

            WebSocket webSocket = client.newWebSocket(
                    new Request.Builder().url(authUrl).build(),
                    new WebSocketListener() {
                        StringBuilder responseBuilder = new StringBuilder();

                        @Override
                        public void onMessage(WebSocket webSocket, String text) {
                            JSONObject response = JSON.parseObject(text);
                            if (response.getJSONObject("header").getInteger("code") == 0) {
                                JSONObject payload = response.getJSONObject("payload");
                                String content = payload.getJSONObject("choices")
                                        .getJSONArray("text")
                                        .getJSONObject(0)
                                        .getString("content");
                                responseBuilder.append(content);

                                // 如果是最后一条消息，完成Future
                                if (response.getJSONObject("header").getInteger("status") == 2) {
                                    responseFuture.complete(responseBuilder.toString());
                                    webSocket.close(1000, "正常关闭");
                                }
                            } else {
                                responseFuture.completeExceptionally(
                                        new RuntimeException("调用星火API失败: " + response.getJSONObject("header").getString("message"))
                                );
                                webSocket.close(1000, "错误关闭");
                            }
                        }

                        @Override
                        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                            responseFuture.completeExceptionally(t);
                        }
                    }
            );

            // 发送请求消息
            webSocket.send(buildRequestMessage(content));

            // 等待响应，设置30秒超时
            return responseFuture.get(30, TimeUnit.SECONDS);

        } catch (Exception e) {
            log.error("调用星火API异常", e);
            throw new RuntimeException("AI服务暂时不可用");
        }
    }

    private String getAuthUrl() throws Exception {
        String host = apiUrl.replace("wss://", "").split("/")[0];

        // 获取GMT时间
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());

        // 拼接签名字符串
        String signatureOrigin = "host: " + host + "\n" +
                "date: " + date + "\n" +
                "GET /v4.0/chat HTTP/1.1";

        // 计算签名
        Mac mac = Mac.getInstance("hmacsha256");
        mac.init(new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256"));
        byte[] signData = mac.doFinal(signatureOrigin.getBytes(StandardCharsets.UTF_8));
        String signature = Base64.getEncoder().encodeToString(signData);

        // 组装鉴权字符串
        String authorizationOrigin = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"",
                apiKey, "hmac-sha256", "host date request-line", signature);

        // 进行Base64编码
        String authorization = Base64.getEncoder().encodeToString(authorizationOrigin.getBytes(StandardCharsets.UTF_8));

        // URL编码处理
        String encodedAuth = java.net.URLEncoder.encode(authorization, StandardCharsets.UTF_8.name());
        String encodedDate = java.net.URLEncoder.encode(date, StandardCharsets.UTF_8.name());

        // 构建鉴权URL
        return String.format("%s?authorization=%s&date=%s&host=%s",
                apiUrl, encodedAuth, encodedDate, host);
    }

    private String buildRequestMessage(String content) {
        Map<String, Object> message = new HashMap<>();

        // header
        Map<String, String> header = new HashMap<>();
        header.put("app_id", appId);
        header.put("uid", UUID.randomUUID().toString().replace("-", ""));
        message.put("header", header);

        // parameter
        Map<String, Object> parameter = new HashMap<>();
        Map<String, Object> chat = new HashMap<>();
        chat.put("domain", "4.0Ultra");     // 修改为 4.0Ultra，这是v4.0版本API的正确domain值
        chat.put("temperature", 0.5);
        chat.put("max_tokens", 2048);
        parameter.put("chat", chat);
        message.put("parameter", parameter);

        // payload
        Map<String, Object> payload = new HashMap<>();
        Map<String, Object> messageContent = new HashMap<>();
        List<Map<String, String>> textList = new ArrayList<>();

        // 添加系统角色消息
        Map<String, String> systemText = new HashMap<>();
        systemText.put("role", "system");
        systemText.put("content", "你是一个专业的心理咨询助手，请用专业、温和的语气回复用户。");
        textList.add(systemText);

        // 添加用户消息
        Map<String, String> userText = new HashMap<>();
        userText.put("role", "user");
        userText.put("content", content);
        textList.add(userText);

        messageContent.put("text", textList);
        payload.put("message", messageContent);
        message.put("payload", payload);

        return JSON.toJSONString(message);
    }

    /**
     * 根据用户第一条消息生成会话标题
     */
    private String generateTitle(String content) {
        // 如果内容太长，截取前20个字符
        if (content.length() > 20) {
            return content.substring(0, 20) + "...";
        }
        return content;
    }

    private String buildSystemPrompt(Long testResultId) {
        if (testResultId == null) {
            return "你是一位专业的心理咨询助手，请基于专业知识为用户提供建议和支持。";
        }

        TestResult testResult = testResultService.getById(testResultId);
        if (testResult == null) {
            return "你是一位专业的心理咨询助手，请基于专业知识为用户提供建议和支持。";
        }

        // 构建更专业的系统提示词
        StringBuilder prompt = new StringBuilder();
        prompt.append("你是一位专业的心理咨询助手，用户刚完成了心理测试。测试结果如下：\n");
        prompt.append("- 测试类型：抑郁症筛查量表(SDS)\n");
        prompt.append("- 总分：").append(testResult.getTotalScore()).append("\n");
        prompt.append("- 状态：").append(testResult.getLevel()).append("\n");

        // 添加维度得分信息
        Map<String, Double> dimensionScores = JSON.parseObject(testResult.getDimensionScores(),
                new TypeReference<Map<String, Double>>() {});
        if (dimensionScores != null) {
            prompt.append("维度得分：\n");
            prompt.append("- 躯体维度：").append(dimensionScores.get("SOMATIC")).append("\n");
            prompt.append("- 认知维度：").append(dimensionScores.get("COGNITIVE")).append("\n");
            prompt.append("- 情感维度：").append(dimensionScores.get("EMOTIONAL")).append("\n");
            prompt.append("- 精神运动维度：").append(dimensionScores.get("PSYCHOMOTOR")).append("\n");
        }

        prompt.append("\n请基于以上测试结果，结合专业知识为用户提供针对性的建议和支持。");
        return prompt.toString();
    }

    private String buildWelcomeMessage(Long testResultId) {
        if (testResultId == null) {
            return "您好！我是您的AI心理咨询助手。我可以帮助您缓解压力、改善情绪，让我们开始对话吧！";
        }

        TestResult testResult = testResultService.getById(testResultId);
        if (testResult == null) {
            return "您好！我是您的AI心理咨询助手。我可以帮助您缓解压力、改善情绪，让我们开始对话吧！";
        }

        StringBuilder message = new StringBuilder();
        message.append("您好！我已经了解了您的心理测试结果。\n\n");
        message.append("测试显示您目前的状态为").append(testResult.getLevel());
        message.append("（总分：").append(testResult.getTotalScore()).append("分）。\n\n");

        // 根据不同程度给出不同的初始回应
        switch (testResult.getLevel()) {
            case "正常":
                message.append("您的心理状态处于健康范围，这很好！不过我们仍可以聊聊如何进一步提升心理健康。");
                break;
            case "轻度抑郁":
                message.append("测试结果显示您可能有一些情绪困扰，这是很常见的情况。让我们一起探讨如何改善心情、缓解压力。");
                break;
            case "中度抑郁":
                message.append("您最近的心理状态似乎不太理想，这确实需要重视。我很理解这种感受，让我们聊聊您的具体困扰。");
                break;
            case "重度抑郁":
                message.append("从测试结果来看，您当前的情绪状态比较困难。建议您同时考虑寻求专业心理咨询师的帮助。在这里，我也会尽力为您提供支持。");
                break;
        }

        message.append("\n\n您现在想聊些什么？或者有什么想和我分享的吗？");
        return message.toString();
    }

    private String buildTestResultAnalysis(TestResult testResult) {
        StringBuilder analysis = new StringBuilder();
        analysis.append("我已经仔细分析了您的测试结果。\n\n");

        // 添加总体状况分析
        analysis.append("【总体状况】\n");
        analysis.append("您的测试总分为 ").append(testResult.getTotalScore()).append(" 分，");
        analysis.append("表明您目前处于").append(testResult.getLevel()).append("状态。\n\n");

        // 添加维度分析
        Map<String, Double> dimensionScores = JSON.parseObject(testResult.getDimensionScores(),
                new TypeReference<Map<String, Double>>() {});
        if (dimensionScores != null && !dimensionScores.isEmpty()) {
            analysis.append("【各维度详细分析】\n");

            // 躯体维度分析
            Double somaticScore = dimensionScores.get("SOMATIC");
            analysis.append("1. 躯体表现：").append(somaticScore != null ? somaticScore : 0).append("分\n");
            if (somaticScore != null && somaticScore > 15) {
                analysis.append("   - 您可能存在睡眠质量下降、食欲改变或身体不适等躯体症状\n");
                analysis.append("   - 建议：保持规律作息，适度运动，注意营养均衡\n");
            }

            // 认知维度分析
            Double cognitiveScore = dimensionScores.get("COGNITIVE");
            analysis.append("\n2. 认知状况：").append(cognitiveScore != null ? cognitiveScore : 0).append("分\n");
            if (cognitiveScore != null && cognitiveScore > 15) {
                analysis.append("   - 表现为注意力难以集中、记忆力下降或决策困难等\n");
                analysis.append("   - 建议：进行适度的认知训练，培养积极思维方式\n");
            }

            // 情感维度分析
            Double emotionalScore = dimensionScores.get("EMOTIONAL");
            analysis.append("\n3. 情感状态：").append(emotionalScore != null ? emotionalScore : 0).append("分\n");
            if (emotionalScore != null && emotionalScore > 15) {
                analysis.append("   - 可能出现情绪低落、易怒或焦虑等情绪波动\n");
                analysis.append("   - 建议：学习情绪管理技巧，寻找适当的情绪宣泄方式\n");
            }

            // 精神运动维度分析
            Double psychomotorScore = dimensionScores.get("PSYCHOMOTOR");
            analysis.append("\n4. 精神运动：").append(psychomotorScore != null ? psychomotorScore : 0).append("分\n");
            if (psychomotorScore != null && psychomotorScore > 15) {
                analysis.append("   - 表现为行为迟缓或烦躁不安等\n");
                analysis.append("   - 建议：培养兴趣爱好，保持适度的社交活动\n");
            }
        }

        // 根据不同程度提供针对性建议
        analysis.append("\n【具体建议】\n");
        switch (testResult.getLevel()) {
            case "正常":
                analysis.append("虽然您目前的心理状态处于健康范围，但仍建议：\n");
                analysis.append("1. 继续保持良好的生活习惯\n");
                analysis.append("2. 培养积极的兴趣爱好\n");
                analysis.append("3. 保持规律的运动习惯\n");
                analysis.append("4. 维持健康的社交关系\n");
                break;

            case "轻度抑郁":
                analysis.append("您目前可能遇到一些情绪困扰，建议：\n");
                analysis.append("1. 建立规律的作息时间表\n");
                analysis.append("2. 每天进行30分钟以上的有氧运动\n");
                analysis.append("3. 学习简单的放松技巧（如深呼吸、渐进性肌肉放松）\n");
                analysis.append("4. 与信任的朋友或家人分享感受\n");
                analysis.append("5. 记录每天的心情变化和积极事件\n");
                break;

            case "中度抑郁":
                analysis.append("您的情况需要更多关注和支持，强烈建议：\n");
                analysis.append("1. 及时预约心理咨询师进行专业辅导\n");
                analysis.append("2. 制定详细的每日计划，避免过度空闲\n");
                analysis.append("3. 培养正念意识，关注当下感受\n");
                analysis.append("4. 寻求家人和朋友的支持和理解\n");
                analysis.append("5. 适当参与团体活动，避免社交孤立\n");
                break;

            case "重度抑郁":
                analysis.append("您当前的状况需要立即采取行动：\n");
                analysis.append("1. 强烈建议立即寻求专业心理医生的帮助\n");
                analysis.append("2. 告知家人或信任的朋友，获取支持和陪伴\n");
                analysis.append("3. 确保规律作息和营养均衡\n");
                analysis.append("4. 避免做重要决定\n");
                analysis.append("5. 远离可能造成伤害的物品\n");
                analysis.append("6. 记录紧急求助电话\n");
                break;
        }

        // 个性化分析和建议
        if (!StringUtils.isEmpty(testResult.getAnalysis())) {
            analysis.append("\n【个性化分析】\n").append(testResult.getAnalysis());
        }

        if (!StringUtils.isEmpty(testResult.getSuggestions())) {
            analysis.append("\n\n【专业建议】\n").append(testResult.getSuggestions());
        }

        // 结束语
        analysis.append("\n\n您想针对哪个方面进行更深入的交流吗？我可以为您提供更具体的建议和支持。");

        return analysis.toString();
    }
} 